/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package chatbot.irc;

import java.io.BufferedReader;
import java.net.Socket;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.prefs.*;
import java.util.SortedSet;
import java.util.concurrent.ConcurrentSkipListSet;
import java.util.Collections;
import chatbot.base.*;
import chatbot.base.event.*;

public class IRCConnection extends Thread implements ChatConnection{
    Status status;
    SortedSet<ChatRoom> rooms;
    String hostname;
    int port;
    String username;
    String password;
    IRCLoginMethod lm;
    int timeout = 1000*60*15;

    Socket conn;
    BufferedReader in;
    PrintWriter out;
    Event connect, disconnect, preferences;

    public IRCConnection() {
        status = Status.OFFLINE;
        connect = new ConnectionEvent("ConnectionConnect", this);
        disconnect = new ConnectionEvent("ConnectionDisconnect", this);
        preferences = new ConnectionEvent("ConnectionPreferences", this);
    }

    public void setPreferences(Preferences prefs) {
        hostname = prefs.get("irc.hostname", "irc.nexuswar.com");
        port = Integer.parseInt(prefs.get("irc.port", "6667"));
        username = prefs.get("irc.botname", "ChatBot");
        password = prefs.get("irc.password", "");
        String temp = prefs.get("irc.loginmethod", "NickServ");
        if (temp.equals("Q")) {
            lm = new IRCQLogin();
        } else if (temp.equals("NickServ")) {
            lm = new IRCNickServLogin();
        } else {
            try {
                lm = (IRCLoginMethod)Class.forName(temp).newInstance();
            } catch(Exception e) {
                System.err.println("Failed to load 'irc.loginmethod'.");
            }
        }
        preferences.alertListeners();
    }

    public void connect() throws Exception {
        conn = new Socket(hostname, port);
        status = Status.CONNECTED;
        conn.setSoTimeout(timeout);
        lm.setConnection(this);
        in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));
        out = new PrintWriter(new OutputStreamWriter(conn.getOutputStream(), "UTF-8"));
        start();
        lm.login(username, password);
        doUser(username);
        status = Status.ONLINE;
        connect.alertListeners();
    }

    @Override
    public void run() {
        try {
            String temp;
            while ((temp = in.readLine()) != null) {
                parseLine(temp);
            }
        } catch (Exception e) {
            close();
        } finally {
            close();
        }
    }

    public void sendMessage(String message) {
        out.write(message);
        out.write("\r\n");
        out.flush();
        System.err.println(message);
    }

    public void doPong(String ping) {
        sendMessage("PONG " + username + ping);
    }
    
    public void doUser(String username) {
        sendMessage("USER "+ username +" "+ conn.getLocalAddress().getHostAddress() +" "+ hostname +" :"+ username);
    }

    public void disconnect() {
        sendMessage("EXIT ");
        close();
        disconnect.alertListeners();
    }

    public void close() {
        try {
            in.close();
            out.close();
            conn.close();
        } catch(Exception e) {
            
        }
    }

    public void parseLine(String line) {
        System.err.println(line);
        int c = 0;
        if (line.charAt(0) == ':') {
            c = 1;
        } 
        String[] command = line.split(" ");
        int cmd = -1;
        try {
            cmd = Integer.parseInt(command[c]);
        } catch (Exception e) {}
        if (cmd != -1) {

        } else {
            if (command[c].equalsIgnoreCase("PING")) {
                doPong(command[c+1]);
            }
        }
    }

    public SortedSet<ChatRoom> getRooms() {
        return rooms;
    }

    public Status getStatus() {
        return status;
    }
}
